package com;
import com.book.constrains.SystemConstants;
import com.book.pojo.Admin;
import com.book.pojo.Book;
import com.book.pojo.BorrowRecord;
import com.book.pojo.Reader;
import com.book.protocol.Protocol;


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Scanner;

public class Client {
    private static Scanner sc = new Scanner(System.in);
    private static Socket socket;
    private static String adminLogin = null;
    //学生登录状态
    private static String readerLogin = null;

    //初始化--连接服务器
    private static void connectToServer() {
        try {
            // 从配置文件中获取地址和端口
            ResourceBundle bundle = ResourceBundle.getBundle("config");
            String addr = bundle.getString("server.addr");
            int port = Integer.parseInt(bundle.getString("server.port"));
            socket = new Socket(addr, port);  // 与服务器建立连接
        } catch (IOException e) {
            System.out.println("连接服务器失败: " + e.getMessage());
            throw new RuntimeException("无法连接到服务器");
        }
    }


    public static void main(String[] args) {
        System.out.println("图书管理系统");
        System.out.println("1.管理员登录");
        System.out.println("2.用户登录");
        System.out.println("3.退出");
        String choice = sc.nextLine();
        switch (choice) {
            case "1":
                adminLogin();
                break;
            case "2":
                readerLogin();
                break;
            case "3":
                System.out.println("退出系统");
                break;
        }
    }

    private static void adminLogin() {
        try {
            // 连接服务器
            connectToServer();  // 这里确保连接服务器

            System.out.println("管理员登录");
            System.out.println("请输入用户名:");
            String username = sc.nextLine();
            System.out.println("请输入密码:");
            String password = sc.nextLine();

            Admin admin = new Admin();
            admin.setUsername(username);
            admin.setPassword(password);

            // 创建协议对象封装登录信息
            Protocol<Admin> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_ADMIN);  // 设置请求类型为管理员
            protocol.setOpt(SystemConstants.ADMIN_LOGIN);  // 设置操作类型为管理员登录
            protocol.setData(admin);  // 设置数据为 Admin 对象

            // 发送登录请求
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器的响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol backProtocol = (Protocol) ois.readObject();

            // 判断登录结果
            if (backProtocol.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                adminLogin = username;  // 登录成功，记住管理员用户名
                System.out.println("登录成功！=======client");
                // 显示管理员操作菜单
                showAdminMenu();
            } else {
                // 登录失败
                adminLogin = null;
                System.out.println("登录失败，请检查用户名或密码。");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("登录过程中出现错误：" + e.getMessage());
        }
    }


    private static void showAdminMenu() {
        if (adminLogin == null) {
            System.out.println("请先登录");
            return;
        } else {
            // 可循环操作的菜单
            while (true) {
                System.out.println("欢迎：" + adminLogin + " 登录！");
                System.out.println("*****图书管理系统*****");
                System.out.println("1.图书管理");
                System.out.println("2.读者管理");
                System.out.println("3.退出系统");
                System.out.println("************************");
                System.out.print("请选择：");
                String choose = sc.nextLine();  // 使用 nextLine() 获取用户输入
                switch (choose) {
                    case "1": // 图书管理
                        bookManager();
                        break;
                    case "2": // 读者管理
                        readerManager();
                        break;
                    case "3": // 退出系统
                        System.out.println("谢谢使用！");
                        System.exit(0);
                        break;
                    default:
                        System.out.println("无效选项，请重新选择。");
                }
            }
        }
    }

    //用户登录
    private static void readerLogin(){
        try {
            // 连接服务器
            connectToServer();  // 这里确保连接服务器

            System.out.println("用户登录");
            System.out.println("请输入用户名:");
            String username = sc.nextLine();
            System.out.println("请输入密码:");
            String password = sc.nextLine();

            Reader reader = new Reader();
            reader.setUsername(username);
            reader.setPassword(password);

            // 创建协议对象封装登录信息
            Protocol<Reader> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_READER);  // 设置请求类型为管理员
            protocol.setOpt(SystemConstants.READER_LOGIN);  // 设置操作类型为管理员登录
            protocol.setData(reader);  // 设置数据为 Admin 对象

            // 发送登录请求
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器的响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol backProtocol = (Protocol) ois.readObject();

            // 判断登录结果
            if (backProtocol.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                readerLogin = username;// 登录成功，记住用户名
                System.out.println("登录成功！=======client");
                // 显示用户操作菜单
                showReaderMenu();
            } else {
                // 登录失败
                readerLogin = null;
                System.out.println("登录失败，请检查用户名或密码。");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("登录过程中出现错误：" + e.getMessage());
        }
    }
    //用户菜单
    private static void showReaderMenu(){
        if (readerLogin == null) {
            System.out.println("请先登录");
            return;
        } else {
            // 可循环操作的菜单
            while (true) {
                System.out.println("欢迎：" + readerLogin + " 登录！");
                System.out.println("*****图书管理系统*****");
                System.out.println("1.借阅书籍");
                System.out.println("2.归还书籍");
                System.out.println("3.查询书籍");
                System.out.println("4.查看借阅记录");
                System.out.println("5.退出系统");
                System.out.println("************************");
                System.out.print("请选择：");
                String choose = sc.nextLine();  // 使用 nextLine() 获取用户输入
                switch (choose) {
                    case "1": // 借阅书籍
                        addBorrowBook();
                        break;
                    case "2": // 归还书籍
                        returnBook();
                        break;
                    case "3": // 查询书籍
                        findAllBook();
                        break;
                    case "4": //查看借阅记录
                        findBorrowRecordsByReaderId();
                        break;
                    case "5":
                        System.out.println("谢谢使用！");
                        System.exit(0);
                        break;
                    default:
                        System.out.println("无效选项，请重新选择。");
                }
            }
        }
    }
    //查看借阅记录
    private static void findBorrowRecordsByReaderId(){
        // 这里确保连接服务器
        try {
            System.out.println("输入自己的id");
            int id =sc.nextInt();
            sc.nextLine();  // 清除缓冲区的换行符
            BorrowRecord borrowRecord = new BorrowRecord();
            borrowRecord.setReaderId(id);
            //封装对象发给服务端
            // 创建协议对象封装登录信息
            Protocol<BorrowRecord> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_READER);  // 设置请求类型为读者
            protocol.setOpt(SystemConstants.READER_VIEW_BORROWED_BOOKS);  // 设置操作类型为借书
            protocol.setData(borrowRecord);  // 设置数据为 borrowbook对象

            // 发送查询请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol response = (Protocol) ois.readObject();

            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("查询结果：" + response.getData());  // 输出查询结果
            } else {
                System.out.println("未找到相关图书！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("归还图书时出现错误：" + e.getMessage());
        }
    }
    //查询所有图书
    private static void findAllBook(){
        // 创建协议对象，封装查询请求
        Protocol<String> protocol = new Protocol<>();
        protocol.setType(SystemConstants.TYPE_READER);
        protocol.setOpt(SystemConstants.READER_FINDALL_BOOKS);  // 使用正确的常量
        //protocol.setData(query);

        try {
            // 发送查询请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol response = (Protocol) ois.readObject();

            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("查询结果：" + response.getData());  // 输出查询结果
            } else {
                System.out.println("未找到相关图书！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("查询图书时出现错误：" + e.getMessage());
        }
    }
    //还书
    private static void returnBook(){
        try {
            // 连接服务器
            connectToServer();  // 这里确保连接服务器
            System.out.println("输入想要归还书籍的id");
            int bookId = sc.nextInt();
            sc.nextLine();  // 清除缓冲区的换行符
            BorrowRecord borrowRecord = new BorrowRecord();
            borrowRecord.setBookId(bookId);
            //封装对象发给服务端
            // 创建协议对象封装登录信息
            Protocol<BorrowRecord> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_READER);  // 设置请求类型为读者
            protocol.setOpt(SystemConstants.READER_RETURN_BOOK);  // 设置操作类型为借书
            protocol.setData(borrowRecord);  // 设置数据为 borrowbook对象

            // 发送登录请求
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器的响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol backProtocol = (Protocol) ois.readObject();

            // 判断登录结果
            if (backProtocol.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("===========归还成功！========");
            } else {
                // 登录失败
                System.out.println("归还失败，请检查输入信息是否有误");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
    //借书
    private static void addBorrowBook(){
        try {
            // 连接服务器
            connectToServer();  // 这里确保连接服务器
            System.out.println("输入想要借阅书籍的id");
            int bookId = sc.nextInt();
            System.out.println("输入借阅人的id");
            int readerId = sc.nextInt();
            sc.nextLine();  // 清除缓冲区的换行符
            BorrowRecord borrowRecord = new BorrowRecord();
            borrowRecord.setBookId(bookId);
            borrowRecord.setReaderId(readerId);
            //封装对象发给服务端
            // 创建协议对象封装登录信息
            Protocol<BorrowRecord> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_READER);  // 设置请求类型为读者
            protocol.setOpt(SystemConstants.READER_BORROW_BOOK);  // 设置操作类型为借书
            protocol.setData(borrowRecord);  // 设置数据为 borrowbook对象

            // 发送登录请求
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器的响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol backProtocol = (Protocol) ois.readObject();

            // 判断登录结果
            if (backProtocol.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("借书成功！=======client");
            } else {
                // 登录失败
                System.out.println("借书失败，请检查输入信息是否有误");
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }


    private static void readerManager() {
        while (true) {
            System.out.println("***** 读者管理 *****");
            System.out.println("1. 增加读者");
            System.out.println("2. 删除读者");
            System.out.println("3. 查询读者");
            System.out.println("4. 退出");
            System.out.print("请选择操作：");

            String choice = sc.nextLine();
            switch (choice) {
                case "1":
                    addReader();
                    break;
                case "2":
                    deleteReader();
                    break;
                case "3":
                    queryReaders();
                    break;
//                case "4":
//                    queryReader();
//                    break;
                case "4":
                    return;
                default:
                    System.out.println("无效选项，请重新选择。");
            }
        }
    }

    private static void deleteReader() {
        try {
            System.out.println("客户端：正在发送删除读者请求！！！！！！！！！");

            // 让用户输入要删除的读者 ID
            Scanner scanner = new Scanner(System.in);
            System.out.print("请输入要删除的读者 ID：");
            int readerId = scanner.nextInt();

            // 创建删除请求的协议对象
            Protocol<Integer> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_ADMIN);
            protocol.setOpt(SystemConstants.ADMIN_DELETE_READER); // 确保该常量正确
            protocol.setData(readerId);

            // 发送删除请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();
            System.out.println("客户端：删除读者请求已发送，等待服务器响应");

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol<Integer> response = (Protocol<Integer>) ois.readObject();

            // 处理服务器返回的结果
            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("删除成功！读者 ID：" + response.getData());
            } else {
                System.out.println("删除失败：" + response.getMsg());
            }

        } catch (IOException | ClassNotFoundException e) {
            System.err.println("客户端：删除读者时发生错误：" + e.getMessage());
            e.printStackTrace();
        }
    }


    private static void queryReaders() {
        try {
            // 创建查询协议对象
            Protocol<String> protocol = new Protocol<>();
            protocol.setType(SystemConstants.TYPE_ADMIN);
            protocol.setOpt(SystemConstants.ADMIN_FINDALL_READERS); // 这里确保使用正确的请求类型
            System.out.println("客户端：正在发送查询所有读者的请求");

            // 发送查询请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol<List<Reader>> response = (Protocol<List<Reader>>) ois.readObject();
            System.out.println("客户端：已收到服务器响应");

            // 处理查询结果
            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                List<Reader> readers = response.getData();
                if (readers == null || readers.isEmpty()) {
                    System.out.println("当前没有读者信息！");
                } else {
                    System.out.println("查询到的读者信息如下：");
                    for (Reader reader : readers) {
                        System.out.println("ID: " + reader.getId() + " | 姓名: " + reader.getName() +
                                " | 用户名: " + reader.getUsername() + " | 密码: " + reader.getPassword());
                    }
                }
            } else {
                System.out.println("查询失败，未找到相关读者信息！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("查询读者时出现错误：" + e.getMessage());
            e.printStackTrace();
        }
    }


    private static void addReader() {
        System.out.println("请输入读者姓名：");
        String name = sc.nextLine();
        System.out.println("请输入读者的用户名：");
        String userName = sc.nextLine();
        System.out.println("请输入读者的密码：");
        String password = sc.nextLine();

        Reader newReader = new Reader();
        newReader.setName(name);
        newReader.setUsername(userName);
        newReader.setPassword(password);

        Protocol<Reader> protocol = new Protocol<>();
        protocol.setType(SystemConstants.TYPE_ADMIN);
        protocol.setOpt(SystemConstants.ADMIN_ADD_READER);
        protocol.setData(newReader);

        try {
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol response = (Protocol) ois.readObject();

            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("读者添加成功！");
            } else {
                System.out.println("读者添加失败！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("添加读者时出现错误：" + e.getMessage());
        }
    }

    private static void bookManager() {
        //增加图书
        //删除图书
        //修改图书
        //查询图书
        //退出
        while (true) {
            System.out.println("***** 图书管理 *****");
            System.out.println("1. 增加图书");
            System.out.println("2. 删除图书");
            System.out.println("3. 修改图书");
            System.out.println("4. 查询图书");
            System.out.println("5. 退出");
            System.out.print("请选择操作：");

            String choice = sc.nextLine();
            switch (choice) {
                case "1":
                    addBook();  // 增加图书
                    break;
                case "2":
                    deleteBook();  // 删除图书
                    break;
                case "3":
                    updateBook();  // 修改图书
                    break;
                case "4":
                    queryBook();  // 查询图书
                    break;
                case "5":
                    return;  // 退出到主菜单
                default:
                    System.out.println("无效选项，请重新选择。");
            }
        }
    }

    private static void addBook() {
        System.out.println("请输入图书的书名：");
        String title = sc.nextLine();
        System.out.println("请输入图书的作者：");
        String author = sc.nextLine();
        System.out.println("请输入图书的可借状态（true/false）：");
        boolean available = sc.nextBoolean();
        sc.nextLine();  // 清除缓冲区的换行符

        System.out.println("输入成功");
        // 创建图书对象
        Book newBook = new Book();
        newBook.setTitle(title);
        newBook.setAuthor(author);
        newBook.setAvailable(available);
        System.out.println("创建成功");

        // 创建协议对象封装请求数据
        Protocol<Book> protocol = new Protocol<>();
        protocol.setType(SystemConstants.TYPE_ADMIN);  // 设置请求类型为管理员
        protocol.setOpt(SystemConstants.ADMIN_ADD_BOOK);  // 使用正确的常量
        protocol.setData(newBook);  // 设置请求数据
        System.out.println("设置成功");

        try {
            // 发送请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();
            System.out.println("发送成功");

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol backProtocol = (Protocol) ois.readObject();
            System.out.println("接收成功");

            // 判断服务器返回的响应代码
            if (backProtocol.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("图书添加成功！");
            } else {
                System.out.println("图书添加失败！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("添加图书时出现错误：" + e.getMessage());
        }
    }

    private static void deleteBook() {
        System.out.println("请输入要删除的图书的ID：");
        int bookId = sc.nextInt();
        sc.nextLine();  // 清除缓冲区的换行符

        // 创建协议对象，封装删除请求
        Protocol<Integer> protocol = new Protocol<>();
        protocol.setType(SystemConstants.TYPE_ADMIN);
        protocol.setOpt(SystemConstants.ADMIN_DELETE_BOOK);  // 使用正确的常量
        protocol.setData(bookId);

        try {
            // 发送请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol response = (Protocol) ois.readObject();

            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("图书删除成功！");
            } else {
                System.out.println("图书删除失败！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("删除图书时出现错误：" + e.getMessage());
        }
    }

    private static void updateBook() {
        System.out.println("请输入要修改的图书的ID：");
        int bookId = sc.nextInt();
        sc.nextLine();  // 清除缓冲区的换行符
        System.out.println("请输入新的图书名称：");
        String newTitle = sc.nextLine();
        System.out.println("请输入新的作者：");
        String newAuthor = sc.nextLine();
        System.out.println("请输入新的图书可借状态（true/false）：");
        boolean newAvailable = sc.nextBoolean();
        sc.nextLine();  // 清除缓冲区的换行符

        // 创建更新后的图书对象
        Book updatedBook = new Book();
        updatedBook.setId(bookId);
        updatedBook.setTitle(newTitle);
        updatedBook.setAuthor(newAuthor);
        updatedBook.setAvailable(newAvailable);

        // 创建协议对象，封装更新请求
        Protocol<Book> protocol = new Protocol<>();
        protocol.setType(SystemConstants.TYPE_ADMIN);
        protocol.setOpt(SystemConstants.ADMIN_UPDATE_BOOK);  // 使用正确的常量
        protocol.setData(updatedBook);

        try {
            // 发送请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol response = (Protocol) ois.readObject();

            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("图书修改成功！");
            } else {
                System.out.println("图书修改失败！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("修改图书时出现错误：" + e.getMessage());
        }
    }

    private static void queryBook() {
//        System.out.println("请输入查询条件（图书名称/作者）：");
//        String query = sc.nextLine();

        // 创建协议对象，封装查询请求
        Protocol<String> protocol = new Protocol<>();
        protocol.setType(SystemConstants.TYPE_ADMIN);
        protocol.setOpt(SystemConstants.ADMIN_FINDALL_BOOKS);  // 使用正确的常量
        //protocol.setData(query);

        try {
            // 发送查询请求到服务器
            ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
            oos.writeObject(protocol);
            oos.flush();

            // 接收服务器响应
            ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
            Protocol response = (Protocol) ois.readObject();

            if (response.getCode().equals(SystemConstants.Code.OPT_SUCCESS)) {
                System.out.println("查询结果：" + response.getData());  // 输出查询结果
            } else {
                System.out.println("未找到相关图书！");
            }
        } catch (IOException | ClassNotFoundException e) {
            System.out.println("查询图书时出现错误：" + e.getMessage());
        }
    }
}
